<?php

require_once 'Zend/Validate/Abstract.php';

class Application_Form_Event extends Zend_Form
{

    private $showPersonSelector = true;
    private $showSeriesSelector = true;
    private $showChildeventCategories = true;
    private $showOthereventCategories = true;
    public static $REQUEST_TYPES_EventStatus = array(
	"Angenommen" => "Angenommen",
	"Abgelehnt" => "Abgelehnt",
    );
    public static $REQUEST_TYPES_Childevents = array(
	"Eingewöhnungstermin" => "Eingewöhnungstermin",
	"Fester Termin" => "Fester Termin",
	"Einzeltermin" => "Einzeltermin",
	"Abgesagter Termin" => "Abgesagter Termin",
    );
    public static $REQUEST_TYPES_Otherevents = array(
	"Gesprächstermin" => "Gesprächstermin",
	"Konferenz" => "Konferenz",
	"Fest/Veranstaltung" => "Feste/Veranstaltungen",
	"Sonstiges" => "Sonstiges",
    );
    public $REQUEST_TYPES;
    private static $FREQUENCE = array(
	"ONCE" => "Einmaliger Termin",
	"WEEKLY" => "Wöchentlicher Termin",
    );
    // Mapping keys to db columns
    private static $DB_MAPPING = array(
	"description" => "description",
	"request" => "request",
	"request_additional" => "request_additional",
	"date_from" => "date_from",
	"date_to" => "date_to",
	"event_type" => "event_type",
	"event_status" => "event_status"
    );
    // Mapping Max Length from db
    private static $MAX_LENGTH = array(
	"description" => "2500",
	"request" => "2500",
	"request_additional" => "2500",
	"date_from" => "date_from",
	"date_to" => "date_to",
	"event_type" => "10"
    );

    public function init()
    {
	//Validators
	$this->REQUEST_TYPES = array_merge($this::$REQUEST_TYPES_Childevents, $this::$REQUEST_TYPES_Otherevents);
	$valid_date = new Zend_Validate_Date(array('format' => 'dd.mm.yyyy',));
	$valid_time = new Zend_Validate_Date(array("format" => "H:i:s"));
	$valid_datetime = new Zend_Validate_Date(array('format' => 'dd.MM.yyyy HH:m',));
	$valid_notempty = new Zend_Validate_NotEmpty();
	$valid_enddate = new Fkb_Validate_DateOrderLogic('date_from');
	$valid_series_enddate = new Fkb_Validate_DateOrderLogic('date_to');
	$valid_series = new Fkb_Validate_EventFrequenceNeeded('last_date');
	//$valid_update_denied = new Fkb_Validate_DeniedEvents();
	//Elements
	
	$this->addElement('select', $this::$DB_MAPPING['event_status'], array(
	    'label' => 'Status:* ',
	    'required' => false,
	    'MultiOptions' => ($this::$REQUEST_TYPES_EventStatus),
	    'validators' => array($valid_notempty/*, $valid_update_denied*/)
	));
	
	$this->addElement('select', $this::$DB_MAPPING['event_type'], array(
	    'label' => 'Kategorie:* ',
	    'required' => true,
	    'MultiOptions' => ($this->REQUEST_TYPES),
	    'validators' => array($valid_notempty)
	));
	if ($this->showPersonSelector === true)
	{
	    $this->addElement('select', 'child_id', array(
		'label' => 'Kind*',
		'required' => false,
		'multiOptions' => $this->createSelectFieldsFromChilds()
	    ));
	}

	$this->addElement('textarea', $this::$DB_MAPPING['description'], array(
	    'label' => 'Beschreibung des Termins:',
	    'required' => false,
	    'filters' => array('StringTrim'),
	    'validators' => array($valid_notempty,
		array(
		    "StringLength",
		    false,
		    array(
			'max' => $this::$MAX_LENGTH['description'])),
		)));

	$this->addElement('text', $this::$DB_MAPPING['date_from'], array(
	    'label' => 'Startdatum:*',
	    'required' => true,
	    'filters' => array('StringTrim'),
	    'validators' => array($valid_notempty, $valid_datetime)
	));

	$this->addElement('text', $this::$DB_MAPPING['date_to'], array(
	    'label' => 'Enddatum:* ',
	    'required' => true,
	    'filters' => array('StringTrim'),
	    'validators' => array($valid_notempty, $valid_datetime, $valid_enddate )
	)
		);


	if ($this->showSeriesSelector === true)
	{
	    $this->addElement('select', 'frequence', array(
		'label' => 'Frequenz:* ',
		'required' => true,
		'MultiOptions' => ($this::$FREQUENCE),
		'validators' => array($valid_series)
	    ));
	}
	$element = $this->createElement('text', 'last_date');
	$element->setLabel('Letztmalig am:* ');
	$element->setRequired(false);
	$element->addFilter('StringTrim');
	$element->addValidators(array($valid_notempty, $valid_date, $valid_series_enddate));
	//$element->addValidators(array($valid_notempty, $valid_date));
	$element->setAttrib('style', 'display:none');
	$element->getDecorator('label')->setOption('style', 'display:none');
	$this->addElement($element);
	$this->addElement('submit', 'add_event', array(
	    'ignore' => true,
	    'label' => 'Termin hinzufügen',
	));
    }

    public function setShowPersonSelector($newValue)
    {
	if (is_bool($newValue))
	    $this->showPersonSelector = $newValue;
    }

    public function setShowSeriesSelector($newValue)
    {
	if (is_bool($newValue))
	    $this->showSeriesSelector = $newValue;
    }

    public function setShowChildeventCategories($newValue)
    {
	if (is_bool($newValue))
	    $this->showChildeventCategories = $newValue;
	$this->buildEventCategories();
    }

    public function setShowOthereventCategories($newValue)
    {
	if (is_bool($newValue))
	    $this->showOthereventCategories = $newValue;
	$this->buildEventCategories();
    }

    private function buildEventCategories()
    {
	if ($this->showChildeventCategories === true && $this->showOthereventCategories === true)
	    $this->REQUEST_TYPES = array_merge($this::$REQUEST_TYPES_Childevents, $this::$REQUEST_TYPES_Otherevents);
	elseif ($this->showChildeventCategories === true && $this->showOthereventCategories !== true)
	    $this->REQUEST_TYPES = $this::$REQUEST_TYPES_Otherevents;
	else
	    $this->REQUEST_TYPES = $this::$REQUEST_TYPES_Childevents;
    }

    /**
     * Converts a child array to select fields
     */
    function createSelectFieldsFromChilds()
    {
	$modelChild = new Model_Child;
	$childs = $modelChild->listAll();

	$selectChilds = array();
	foreach ($childs as $child)
	{
	    $selectChilds[$child['id']] = $child['forename'] . " " . $child['surname'];
	}
	return $selectChilds;
    }

    public function setEventTypes(array $categories)
    {
	$this->getElement($this::$DB_MAPPING['event_type'])->setOptions(array('MultiOptions' => $this->array2map($categories)));
    }
    
    public function setEventTypesToChildEvents(){
	$this->clearEventTypes();
	$this->setEventTypes(self::$REQUEST_TYPES_Childevents);
    }
    
    public function setEventTypesToOtherEvents(){
	$this->clearEventTypes();
	$this->setEventTypes(self::$REQUEST_TYPES_Otherevents);
    }


    public function resetEventTypes()
    {
	$this->getElement($this::$DB_MAPPING['event_type'])->setOptions(array('MultiOptions' => $this->array2map($this::$REQUEST_TYPES)));
    }

    public function clearEventTypes()
    {
	$this->getElement($this::$DB_MAPPING['event_type'])->setOptions(array('MultiOptions' => array()));
    }

    private function array2map($array)
    {
	$map = array();
	foreach ($array as $value)
	{
	    $map[$value] = $value;
	}
	return $map;
    }

    public function setMultiPersonSelect($multipleSelectPersons)
    {
	if ($multipleSelectPersons === TRUE)
	{
	    $this->getElement('child_id')->setAttrib('multiple', 'multiple');
	} else
	{
	    $this->getElement('child_id')->setAttrib('multiple', '');
	}
    }

    public function loadPersonsByPersonType($personTypes)
    {
	$this->getElement('child_id')->setOptions(array('MultiOptions' => $this->convertPersonsToSelectList($this->getPersonsFromDb($personTypes))));
    }

    public function loadChildsOnly()
    {
	$this->loadPersonsByPersonType(array('Kind'));
    }

    public function loadAllPersons()
    {
	$this->getElement('child_id')->setOptions(array('MultiOptions' => $this->convertPersonsToSelectList($this->getPersonsFromDb())));
    }

    private function convertPersonsToSelectList($persons)
    {
	$selectPersons = array();
	foreach ($persons as $person)
	{
	    $selectPersons[$person['id']] = $person['forename'] . " " . $person['surname'];
	}
	return $selectPersons;
    }

    public function setSelectedPersons($persons)
    {
	if (is_array($persons))
	{
	    $this->getElement('child_id')->setValue($persons);
	} else
	{
	    $this->getElement('child_id')->setValue(array($persons));
	}
    }

    private function getPersonsFromDb($personTypes = NULL)
    {
	$modelPerson = new Model_Person();
	if ($personTypes === NULL)
	{
	    return $modelPerson->listAll();
	} else
	{
	    return $modelPerson->listByPersonTypes($personTypes);
	}
    }

    public function setLastDateVisible($isVisible)
    {
	$element = $this->getElement('last_date');
	$styleInfo = '';
	if ($isVisible)
	{
	    $styleInfo = 'display:block';
	} else
	{
	    $styleInfo = 'display:none';
	}
	$element->setAttrib('style', $styleInfo);
	$element->getDecorator('label')->setOption('style', $styleInfo);
    }

    /*
     * @deprecated
     * use setSelectedPersons($persond) instead!
     */

    public function preselectChild($childId)
    {
	$this->setSelectedPersons($childId);
    }

    public function disableElement($elementId)
    {
	$elem = $this->getElement($elementId);
	$elem->setAttrib('disabled', true);
	$elem->setAttrib('readonly', true);
    }

    public function removeAllMultioptionsExcept($elementId, $optionParam)
    {
	$elem = $this->getElement($elementId);
	$optionArray = $elem->getMultioptions();
	foreach ($optionArray as $key => $option)
	{
	    if ($key != $optionParam)
		$elem->removeMultioption($key);
	}
    }

    public function addInCaretimeValidator()
    {
	$inCaretimeValidator = new Fkb_Validate_InCaretime;
	$this->getElement('date_from')->addValidator($inCaretimeValidator);
	$this->getElement('date_to')->addValidator($inCaretimeValidator);
    }
    public function addDateOrderLogicValidator()
    {
	$logicDateOrder = new Fkb_Validate_DateOrderLogic;
	$this->getElement('date_from', 'date_to')->addValidator($logicDateOrder);
	//$this->getElement('date_from')->addValidator($inCaretimeValidator);
	//$this->getElement('date_to')->addValidator($inCaretimeValidator);
    }
    
}

